package com.yudean.esb.domain.erp;

import com.yudean.esb.domain.esb.EsbRecvServiceTempData;
import jodd.vtor.Check;
import jodd.vtor.ValidationContext;
import jodd.vtor.Vtor;
import jodd.vtor.constraint.NotNullConstraint;
import org.dozer.DozerBeanMapper;
import org.dozer.loader.api.BeanMappingBuilder;
import org.dozer.loader.api.FieldDefinition;
import org.dozer.loader.api.TypeMappingOptions;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;

import static org.dozer.loader.api.FieldsMappingOptions.hintA;
import static org.dozer.loader.api.FieldsMappingOptions.hintB;

public class ErpControl implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 4871157446507319907L;

    private Long controlId;

    private String sourceCode;

    private String sourceCompCode;

    private String targetCode;

    private String targetCompCode;

    private String targetModel;

    private String processStatus;

    private String receiveStatus;

    private Integer recordCount;

    private String errorMessage;

    private Date creationDate;
    private String creationDateStr;
    private Integer createdBy;

    private Date lastUpdateDate;
    private String lastUpdateDateStr;

    private Integer lastUpdatedBy;

    private String attribute1;

    private String attribute2;

    private String attribute3;

    private String attribute4;

    private String attribute5;

    private String attribute6;

    private String attribute7;

    private String attribute8;

    private String attribute9;

    private String attribute10;

    public long getControlId() {
        return controlId;
    }

    public void setControlId(long controlId) {
        this.controlId = controlId;
    }

    public String getSourceCode() {
        return sourceCode;
    }

    public void setSourceCode(String sourceCode) {
        this.sourceCode = sourceCode;
    }

    public String getSourceCompCode() {
        return sourceCompCode;
    }

    public void setSourceCompCode(String sourceCompCode) {
        this.sourceCompCode = sourceCompCode;
    }

    public String getTargetCode() {
        return targetCode;
    }

    public void setTargetCode(String targetCode) {
        this.targetCode = targetCode;
    }

    public String getTargetCompCode() {
        return targetCompCode;
    }

    public void setTargetCompCode(String targetCompCode) {
        this.targetCompCode = targetCompCode;
    }

    public String getTargetModel() {
        return targetModel;
    }

    public void setTargetModel(String targetModel) {
        this.targetModel = targetModel;
    }

    public String getProcessStatus() {
        return processStatus;
    }

    public void setProcessStatus(String processStatus) {
        this.processStatus = processStatus;
    }

    public String getReceiveStatus() {
        return receiveStatus;
    }

    public void setReceiveStatus(String receiveStatus) {
        this.receiveStatus = receiveStatus;
    }

    public Integer getRecordCount() {
        return recordCount;
    }

    public void setRecordCount(Integer recordCount) {
        this.recordCount = recordCount;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public String getCreationDateStr() {
        return creationDateStr;
    }

    public void setCreationDateStr(String creationDateStr) {
        this.creationDateStr = creationDateStr;
        this.creationDate = longDateParser(creationDateStr);
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }

    public Date getLastUpdateDate() {
        return lastUpdateDate;
    }

    public void setLastUpdateDate(Date lastUpdateDate) {
        this.lastUpdateDate = lastUpdateDate;
    }

    public String getLastUpdateDateStr() {
        return lastUpdateDateStr;
    }

    public void setLastUpdateDateStr(String lastUpdateDateStr) {
        this.lastUpdateDateStr = lastUpdateDateStr;
        this.lastUpdateDate = longDateParser(lastUpdateDateStr);
    }

    public Integer getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(Integer lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    }

    public String getAttribute1() {
        return attribute1;
    }

    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }

    public String getAttribute2() {
        return attribute2;
    }

    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }

    public String getAttribute3() {
        return attribute3;
    }

    public void setAttribute3(String attribute3) {
        this.attribute3 = attribute3;
    }

    public String getAttribute4() {
        return attribute4;
    }

    public void setAttribute4(String attribute4) {
        this.attribute4 = attribute4;
    }

    public String getAttribute5() {
        return attribute5;
    }

    public void setAttribute5(String attribute5) {
        this.attribute5 = attribute5;
    }

    public String getAttribute6() {
        return attribute6;
    }

    public void setAttribute6(String attribute6) {
        this.attribute6 = attribute6;
    }

    public String getAttribute7() {
        return attribute7;
    }

    public void setAttribute7(String attribute7) {
        this.attribute7 = attribute7;
    }

    public String getAttribute8() {
        return attribute8;
    }

    public void setAttribute8(String attribute8) {
        this.attribute8 = attribute8;
    }

    public String getAttribute9() {
        return attribute9;
    }

    public void setAttribute9(String attribute9) {
        this.attribute9 = attribute9;
    }

    public String getAttribute10() {
        return attribute10;
    }

    public void setAttribute10(String attribute10) {
        this.attribute10 = attribute10;
    }

    /**
     * 判断是否有不满足的约束的地方
     *
     * @return
     */
    public boolean hasViolations() {
        if (validationContext == null)
            validationContext = getValidationContext();
        Vtor vtor = new Vtor();
        vtor.validate(validationContext, this);
        return vtor.hasViolations();
    }

    /**
     * 用来构造验证字段的上下文
     *
     * @return
     */
    private static ValidationContext getValidationContext() {
        ValidationContext vctx = new ValidationContext();
        vctx.add(new Check("controlId", new NotNullConstraint()));
        return vctx;
    }

    // 验证的条件
    private static ValidationContext validationContext = null;
    // 时间转换器，因为发送过来的时间是LONG型，但是也要兼容标准格式
    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static DozerBeanMapper mapper;
    //
    //控制表的映射关系
    private static BeanMappingBuilder controlMapping = new BeanMappingBuilder() {
        @Override
        protected void configure() {
            //对于日期的转换
            String dateFormat = "yyyy-MM-dd HH:mm:ss";
            mapping(Map.class, ErpControl.class,
                    TypeMappingOptions.dateFormat(dateFormat))
                    .fields(getMapperDefine("ATTRIBUTE1"),
                            "controlId",
                            hintA(String.class),
                            hintB(Long.class))
                    .fields(getMapperDefine("ATTRIBUTE2"), "sourceCode")
                    .fields(getMapperDefine("ATTRIBUTE3"), "sourceCompCode")
                    .fields(getMapperDefine("ATTRIBUTE4"), "targetCode")
                    .fields(getMapperDefine("ATTRIBUTE5"), "targetCompCode")
                    .fields(getMapperDefine("ATTRIBUTE6"), "targetModel")
                    .fields(getMapperDefine("ATTRIBUTE7"), "processStatus")
                    .fields(getMapperDefine("ATTRIBUTE8"), "receiveStatus")
                    .fields(getMapperDefine("ATTRIBUTE9"),
                            "recordCount",
                            hintA(String.class),
                            hintB(Integer.class))
                    .fields(getMapperDefine("ATTRIBUTE10"), "errorMessage")
                    .fields(getMapperDefine("ATTRIBUTE11"), "creationDate",
                            hintA(String.class),
                            hintB(Date.class))
                    .fields(getMapperDefine("ATTRIBUTE12"),
                            "createdBy",
                            hintA(String.class),
                            hintB(Integer.class))
                    .fields(getMapperDefine("ATTRIBUTE13"), "lastUpdateDate",
                            hintA(String.class),
                            hintB(Date.class))
                    .fields(getMapperDefine("ATTRIBUTE14"),
                            "lastUpdatedBy",
                            hintA(String.class),
                            hintB(Integer.class))
                    .fields(getMapperDefine("ATTRIBUTE21"), "attribute1")
                    .fields(getMapperDefine("ATTRIBUTE22"), "attribute2")
                    .fields(getMapperDefine("ATTRIBUTE23"), "attribute3")
                    .fields(getMapperDefine("ATTRIBUTE24"), "attribute4")
                    .fields(getMapperDefine("ATTRIBUTE25"), "attribute5")
                    .fields(getMapperDefine("ATTRIBUTE26"), "attribute6")
                    .fields(getMapperDefine("ATTRIBUTE27"), "attribute7")
                    .fields(getMapperDefine("ATTRIBUTE28"), "attribute8")
                    .fields(getMapperDefine("ATTRIBUTE29"), "attribute9")
                    .fields(getMapperDefine("ATTRIBUTE30"), "attribute10")
            ;
        }
    };


    static {
        mapper = new DozerBeanMapper();
        mapper.addMapping(controlMapping);
    }

    /**
     * 转换成临时数据存储对象
     *
     * @return 临时对象
     */
    public EsbRecvServiceTempData convert2TmpData() {
        Map<String, Object> data = mapper.map(this, Map.class);
        data.put("ATTRIBUTE99", "FWS-TMP-DATA");

        EsbRecvServiceTempData tmpData = new EsbRecvServiceTempData();
        tmpData.setIsProcessed("1");
        tmpData.setID("FWS-ERP-CONTROL");
        tmpData.setPackageID(this.getControlId() + "");
        tmpData.setOperation("T");
        tmpData.setTransactionID(this.getControlId() + "");

        ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list.add(data);
        tmpData.setData(list);
        return tmpData;
    }

    /**
     * 将临时表的信息转存为合同数据
     *
     * @param tmpData 临时表
     * @return 合同数据集合
     */
    public static ErpControl mapToThis(Map tmpData) {
        if (tmpData == null) {
            return null;
        }
        return mapper.map(tmpData, ErpControl.class);
    }

    /**
     * 需要兼容法务系统发送过来的时间格式：时间戳以及标准格式
     *
     * @param longDate 格式待定
     * @return 时间
     */
    public static Date longDateParser(String longDate) {
        try {
            Long timeVal = Long.parseLong(longDate);
            return new Date(timeVal);
        } catch (Exception ex) {
            try {
                return SIMPLE_DATE_FORMAT.parse(longDate);
            } catch (Exception err) {
                return null;
            }
        }
    }

    /**
     * 获得Map的映射定义
     *
     * @param key 键值
     * @return 映射定义
     */
    protected static FieldDefinition getMapperDefine(String key) {
        return new FieldDefinition("this").mapKey(key);
    }

    @Override
    public String toString() {
        return "ErpControl{" + "controlId=" + controlId + ", sourceCode='"
                + sourceCode + '\'' + ", sourceCompCode='" + sourceCompCode
                + '\'' + ", targetCode='" + targetCode + '\''
                + ", targetCompCode='" + targetCompCode + '\''
                + ", targetModel='" + targetModel + '\'' + ", processStatus='"
                + processStatus + '\'' + ", receiveStatus='" + receiveStatus
                + '\'' + ", recordCount=" + recordCount + ", errorMessage='"
                + errorMessage + '\'' + ", creationDate=" + creationDate
                + ", creationDateStr='" + creationDateStr + '\''
                + ", createdBy=" + createdBy + ", lastUpdateDate="
                + lastUpdateDate + ", lastUpdateDateStr='" + lastUpdateDateStr
                + '\'' + ", lastUpdatedBy=" + lastUpdatedBy + ", attribute1='"
                + attribute1 + '\'' + ", attribute2='" + attribute2 + '\''
                + ", attribute3='" + attribute3 + '\'' + ", attribute4='"
                + attribute4 + '\'' + ", attribute5='" + attribute5 + '\''
                + ", attribute6='" + attribute6 + '\'' + ", attribute7='"
                + attribute7 + '\'' + ", attribute8='" + attribute8 + '\''
                + ", attribute9='" + attribute9 + '\'' + ", attribute10='"
                + attribute10 + '\'' + '}';
    }
}
